<template>
  <h1>对ref函数定义的数据</h1>
  <h2>msg:{{ msg }}</h2>
  <button @click="msg += '!'">修改ref定义的msg</button>
  <h2>number:{{ number }}</h2>
  <button @click="number++">修改ref定义的number</button>
  <h1>超市水果</h1>
  <h2>苹果:{{ supermarket.apple }}</h2>
  <button @click="supermarket.apple++">苹果增加</button>
  <h2>橘子:{{ supermarket.orage }}</h2>
  <button @click="supermarket.orage++">橘子增加</button>
  <h2>深层对象:{{ supermarket.a.b }}</h2>
  <button @click="supermarket.a.b++">深层对象增加</button>
  <hr />
  <h1>一个人的信息</h1>
  <h2>姓名:{{ person.name }}</h2>
  <h2>年龄:{{ person.age }}</h2>
  <h2>薪水:{{ person.job.salary }}K</h2>
  <button @click="person.name += '~'">修改姓名</button>
  <button @click="person.age++">修改年龄</button>
  <button @click="person.job.salary++">涨薪</button>
</template>

<script>
import { ref, reactive, watch } from 'vue'
export default {
  name: 'App',
  setup() {
    const msg = ref('你好啊')
    const number = ref(0)
    const supermarket = ref({
      apple: 10,
      orage: 20,
      a: {
        b: 1,
      },
    })

    const person = reactive({
      name: '洪奇奇',
      age: 18,
      job: {
        salary: 20,
      },
    })

    console.log('msg:', msg)
    console.log('supermarket:', supermarket)

    /*
      1、vue3可以使用多个watch
      2、对于ref()定义的基本数据类型(数字，字符串),直接监听,能正常获取oldVal。不能直接监听.value,相当于直接监听了值，只能用getter函数返回
      3、同时监听多个数据,传入数组newVal, oldVal也是数组，能正常获取oldVal
      4、对于ref()定义的对象,不能正常获取oldVal,默认开启deep:true
    */
    // 分别监听
    /* watch(msg, (newVal, oldVal) => {
      console.log('msg变化:', newVal, oldVal)
    }) */

    // 不能直接监听.value,相当于直接监听了值，只能用getter函数返回
    /* watch(
      () => number.value,
      (newVal, oldVal) => {
        console.log('number变化:', newVal, oldVal)
      }
    ) */

    // 同时监听多个数据
    /* watch([msg, number], (newVal, oldVal) => {
      console.log('msg或number变化:', newVal, oldVal)
    }) */

    // 监听ref()定义的对象,默认开启了deep:true,不能正常获取oldVal
    watch(
      supermarket.value.a,
      (newVal, oldVal) => {
        console.log('supermarket变化:', newVal, oldVal)
      }
      // { deep: true, immediate: true }  //默认开启了deep:true
    )

    // -----------------------------------------------------------------------
    // -----------------------------------------------------------------------
    /*
      1、对于reactive()定义的对象,监听整个对象，默认开启了deep:true，不能正常获取oldVal
      2、监听一个属性()=>，能正常获取oldVal
      3、监听多个属性，数组的形式，两种写法，能正常获取oldVal
      4、监听person中某个对象里深层的值，(以函数返回的形式：需要手动开启deep:true；直接监听则不用),不能正常获取oldVal
    */

    // 监听整个对象，不能正常获取oldVal
    /* watch(person, (newVal, oldVal) => {
      console.log('person变化:', newVal, oldVal)
    }) */

    // 监听一个属性，能正常获取oldVal
    /* watch(
      () => person.name,
      (newVal, oldVal) => {
        console.log('person.name变化:', newVal, oldVal)
      }
    ) */

    // 监听多个属性，数组的形式，能正常获取oldVal
    // 写法一：
    /* watch(
      () => [person.name, person.age],
      (newVal, oldVal) => {
        console.log('person.name或age变化:', newVal, oldVal)
      }
    ) */
    // 写法二:
    /* watch([() => person.name, () => person.age], (newVal, oldVal) => {
      console.log('person.name或age变化:', newVal, oldVal)
    }) */

    // 监听person中某个对象里深层的值，(以函数返回的形式：需要手动开启deep:true；直接监听则不用),不能正常获取oldVal
    /* watch(
      () => person.job,
      (newVal, oldVal) => {
        console.log('person.job变化:', newVal, oldVal)
      },
      { deep: true } //需手动开启深度监听
    ) */
    /* watch(
      person.job,
      (newVal, oldVal) => {
        console.log('person.job变化:', newVal, oldVal)
      }
      // { deep: true } //不需手动开启深度监听
    ) */

    return {
      msg,
      number,
      supermarket,
      person,
    }
    /* 
      总结：
      1、监听单个基本属性，能正常获取oldVal
      2、监听对象，都不能正常返回oldVal
      3、监听多个属性都用数组的形式
      4、对于ref()定义的对象,默认开启deep:true
      5、对于reactive()定义的对象，以函数返回的写法时()=> ,需手动开启deep:true
    */
  },
}
</script>
